package ShoppingCartJFrame;

import java.util.*;

import javax.swing.JFrame;



//This class implements an frame registry where frames
//can locate each other. It is an observable, so if you want
//to wait for a particular class, you can be an observer. This
//is better than the polling you have to do with getApplet.
//
//This class is implemented as a singleton, which means there
//is only one. The single instance is kept in a protected
//static variable and returned by the instance() method.

public class FrameRegistry extends Observable{
	
	// The single copy of the registry
	protected static FrameRegistry registry;
	
	// The table of frames
    protected Hashtable frames;

//Used for generating unique frame names
    protected int nextUnique;
	
    protected FrameRegistry()
    {
         frames = new Hashtable();
         nextUnique = 0;
    }

//Returns the long instance of the registry. If there isn't a registry
//yet, it creates one.

    public synchronized static FrameRegistry instance()
    {
         if (registry == null) {
              registry = new FrameRegistry();
         }
         return registry;
    }
    
 // Adds a new frame to the registry - stores it in the table and
 // sends a notification to its observers.

      public synchronized void addFrame(String name, JFrame newFrame)
      {
           frames.put(name, newFrame);
           setChanged();
           notifyObservers(new FrameRegistryEvent(
                FrameRegistryEvent.ADD_FRAME,
                name, newFrame));
      }
      
   // Adds a new frame to the registry - stores it in the table and
   // sends a notification to its observers. If uniqueName is false, the
   // frame's name is non-unique. Store the frame in a table with a
   // unique version of the name (appends <#> to the name where # is
   // a constantly increasing number).

        public synchronized void addFrame(String name, JFrame newFrame,
             boolean uniqueName)
        {
             if (!uniqueName && (frames.get(name) != null)) {
                  name = name + "<"+nextUnique+">";
                  nextUnique++;
             }

             frames.put(name, newFrame);
             setChanged();
             notifyObservers(new FrameRegistryEvent(
                  FrameRegistryEvent.ADD_FRAME,
                  name, newFrame));
        }
        
     // removes a frame from the table and notifies the observers

        public synchronized void removeFrame(JFrame frame)
        {
             Enumeration e = frames.keys();

             while (e.hasMoreElements()) {
                  Object key = e.nextElement();

                  if (frames.get(key) == frame) {
                       frames.remove(key);
                       setChanged();
                       notifyObservers(new FrameRegistryEvent(
                            FrameRegistryEvent.REMOVE_FRAME,
                            (String)key, frame));
                       return;
                  }
             }
        }
        
        
     // removes a frame from the table and notifies the observers

        public synchronized void removeFrame(String name)
        {
             JFrame frame = (JFrame) frames.get(name);
             if (frame == null) return;

             frames.remove(name);

             setChanged();
             notifyObservers(new FrameRegistryEvent(
                  FrameRegistryEvent.REMOVE_FRAME,
                  name, frame));
        }
        
     // finds a frame by name, or returns null if not found

        public JFrame findFrame(String name)
        {
             return (JFrame) frames.get(name);
        }

   // lets you see all the frames in the registry

        public Enumeration getFrames()
        {
             return frames.elements();
        }


}
